package net.khoroshev.wschat.config;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.jndi.JndiTemplate;

import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * Created with IntelliJ IDEA.
 * Created by: vfirstov
 * Date: 13.11.13
 * Time: 21:24
 *
 */

@Configuration
@PropertySources(value = {@PropertySource("classpath:app.properties")})
public class DataSourcesConfiguration {

    private static Log log = LogFactory.getLog(DataSourcesConfiguration.class);

    @Autowired
    org.springframework.core.env.Environment env;


    @Bean
    public javax.sql.DataSource dataSource() throws NamingException, SQLException {
        javax.sql.DataSource result = null;
        String jndiName = env.getProperty("jdbc.jndiname");
        String driverClassName = env.getProperty("jdbc.driverClassName");
        String jdbcUrl = env.getProperty("jdbc.url");
        String jdbcUser = env.getProperty("jdbc.username");
        String jdbcPass = env.getProperty("jdbc.password");


        if (log.isDebugEnabled()) {
            log.debug("Get dataSource, jndiName = " + jndiName);
        }

        if (jndiName == null
                || jndiName.isEmpty()) {
            try {
                DriverManagerDataSource dataSource = new DriverManagerDataSource();
                dataSource.setDriverClassName(driverClassName);
                dataSource.setUrl(jdbcUrl);
                dataSource.setUsername(jdbcUser);
                dataSource.setPassword(jdbcPass);
                result = dataSource;
            } catch (Throwable t) {
                log.error("Unable to programmatically configure local DS", t);
                throw new RuntimeException("Total failure setting up data source",
                        t);
            }
        } else {
            try {
                JndiTemplate jndi = new JndiTemplate();
                result = (DataSource) jndi.lookup(jndiName);
            } catch (Throwable t) {
                log.error("Unable to take data source from jndi", t);
                throw new RuntimeException("Total failure setting up data source",
                        t);
            }
        }
        return result;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }


    @Value("classpath:db/${dbtype}/db_schema.sql")
    private Resource schemaScript;

    @Value("classpath:db/${dbtype}/init_data.sql")
    private Resource dataScript;

    @Bean
    @Profile("createDB")
    public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
        log.info("Initializing database");
        final DataSourceInitializer initializer = new DataSourceInitializer();
        initializer.setDataSource(dataSource);
        initializer.setDatabasePopulator(databasePopulator());
        return initializer;
    }

    private DatabasePopulator databasePopulator() {
        final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
        populator.addScript(schemaScript);
        populator.addScript(dataScript);
        return populator;
    }


}
